/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.dtgenerator.common;

import com.inspur.edp.bef.bizentity.beenum.RequestNodeTriggerType;
import com.inspur.edp.caf.generator.baseInfo.ParameterInfo;
import com.inspur.edp.cef.designtime.api.element.GspElementDataType;
import com.inspur.edp.cef.designtime.api.operation.ExecutingDataStatus;
import com.inspur.edp.cef.entity.changeset.Util;
import com.inspur.edp.das.commonmodel.IGspCommonElement;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.das.commonmodel.entity.GspCommonObject;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ArrayCreation;
import org.eclipse.jdt.core.dom.ArrayInitializer;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.StringLiteral;

public final class Utils {

  public static final String InterfacePrefix = "I";

  // ORIGINAL LINE: internal static Type GetNativeType(this GspElementDataType elementType)
  public static java.lang.Class getNativeType(GspElementDataType elementType) {
    switch (elementType) {
      case String:
      case Text:
        return String.class;
      case Boolean:
        return Boolean.class;
      case Integer:
        return Integer.class;
      case Decimal:
        return java.math.BigDecimal.class;
      case Date:
      case DateTime:
        return java.util.Date.class;
      case Binary:
        return byte[].class;
      default:
        throw new RuntimeException("invalid enum values" + elementType);
    }
  }

// ORIGINAL LINE: internal static ParameterInfo BuildParGenInfo(this ICompParameter compPar,
  // BEGeneratorContext beGenCtx, string parName = null, Caf.Generator.BaseInfoItem.ParameterMode
  // parMode = Caf.Generator.BaseInfoItem.ParameterMode.In)
  //
  //	public static java.lang.Class  convertPropNativeType(java.lang.Class propType)
  //	{
  //		//单值业务字段
  //		if (propType.getSuperclass() != null && propType.getSuperclass().IsGenericType &&
  // propType.getSuperclass().GetGenericTypeDefinition() == SimpleDataTypeEntity<>.class)
  //		{
  //			return propType.getSuperclass().GetGenericArguments()[0];
  //		}
  //		//普通字段
  //		return propType;
  //	}

  //	/**
  //	 根据EntityData接口获取属性类型;
  //
  //	 @return
  //	*/
  //	public static java.lang.Class  getPropertyType(java.lang.Class host, String propName)
  //	{
//		var pi = host.getProperty(propName);
  //		if (pi != null)
  //		{
  //			return pi.PropertyType;
  //		}
  //
//		for (var baseType : host.getInterfaces())
  //		{
  //			if (baseType == IEntityData.class || baseType == IChildEntityData.class || baseType ==
  // IKey.class)
  //			{
  //				continue;
  //			}
  //			pi = baseType.GetProperty(propName);
  //			if(pi != null)
  //			{
  //				return pi.PropertyType;
  //			}
  //		}
  //		return null;
  //	}

  //	@Autowired
  //	public static FsService fsService;

  //	@Autowired
  //	 public static MetadataProjectService metadataProjService;

  public static String formatExceptionMsg(String msg, String... pars) {
    if (pars != null && pars.length > 0) {
      msg = String.format(msg, pars);
    }
    final String msgFlag = "#GSPBefError#";
    return msgFlag + msg + msgFlag;
  }

  public static String getParameterName(ParameterInfo info) {
    return info.getParamName();
  }

  private static final List<ExecutingDataStatus> changeTypes = Arrays.asList(
          ExecutingDataStatus.added,
          ExecutingDataStatus.Deleted,
          ExecutingDataStatus.Modify);

  public static Expression buildChgTypes(AST ast,
      EnumSet<ExecutingDataStatus> requestNodeTriggerTypes) {
    Objects.requireNonNull(requestNodeTriggerTypes, "requestNodeTriggerTypes");

    int type = requestNodeTriggerTypes.stream().filter(item -> changeTypes.contains(item))
        .distinct().map(item -> item.getValue()).reduce(0, Integer::sum);
    if(type == 0) {
      return ast.newNullLiteral();
    }
    String varName;
    switch (type) {
      case 1:
        varName = "ChgTypes_Add";
        break;
      case 2:
        varName = "ChgTypes_Modify";
        break;
      case 4:
        varName = "ChgTypes_Delete";
        break;
      case 3:
        varName = "ChgTypes_AddModify";
        break;
      case 5:
        varName = "ChgTypes_AddDelete";
        break;
      case 6:
        varName = "ChgTypes_ModifyDelete";
        break;
      case 7:
        varName = "ChgTypes_All";
        break;
      default:
        throw new RuntimeException("" + type);
    }
    return ast.newQualifiedName(ast.newName(Util.class.getTypeName()),ast.newSimpleName(varName));
  }

  //Map<nodeCode(String), elementIdList(List<String>)>
  public static Expression buildRequestChildElements(AST ast, GspCommonObject node, Map el) {
    if (el == null || el.isEmpty()) {
      return ast.newNullLiteral();
    }

    MethodInvocation asListInvocation = ast.newMethodInvocation();
    asListInvocation.setName(ast.newSimpleName("asList"));
    QualifiedName name = ast.newQualifiedName(
        ast.newQualifiedName(ast.newSimpleName("java"), ast.newSimpleName("util")),
        ast.newSimpleName("Arrays"));
    asListInvocation.setExpression(name);

    for (Object pair : el.entrySet()) {
      ClassInstanceCreation classInstanceCreation = ast.newClassInstanceCreation();
      classInstanceCreation.setType(ast.newSimpleType(ast.newSimpleName("ChildElementsTuple")));
      IGspCommonObject childNode = node.getChildObjectById((String) ((Map.Entry) pair).getKey());
      StringLiteral nodeCodeLiteral = ast.newStringLiteral();
      nodeCodeLiteral.setLiteralValue(childNode.getCode());
      classInstanceCreation.arguments().add(nodeCodeLiteral);

      ArrayCreation elementsArrayCreation = ast.newArrayCreation();
      elementsArrayCreation.setType(
          ast.newArrayType(ast.newSimpleType(ast.newSimpleName("String"))));
      ArrayInitializer elementsArrayInitializer = ast.newArrayInitializer();
      for (String elementId : (List<String>) ((Map.Entry) pair).getValue()) {
        IGspCommonElement element = childNode.findElement(elementId);
        StringLiteral elementLableIdLiteral = ast.newStringLiteral();
        elementLableIdLiteral.setLiteralValue(element.getLabelID());
        elementsArrayInitializer.expressions().add(elementLableIdLiteral);
      }
      elementsArrayCreation.setInitializer(elementsArrayInitializer);
      classInstanceCreation.arguments().add(elementsArrayCreation);
      asListInvocation.arguments().add(classInstanceCreation);
    }
    return asListInvocation;
  }

}
